local d = {
    --========CONSTANTS========
    LN = nil,
    -- ...

    --========GLOBAL FUNCTIONS========
    --utils
    UtilRds = nil,
    --incs
    PoolMgr = nil,
    Logger = nil,
    -- ...

    --========LIB=========
    --orms
    Orm = {
        __index = function(t, k)
            ngx.say("orm not init yet")
        end
    },
    --libs
    uuid = require("framework.libs.jit_uuid")
    -- ...
}

--======================================
--default params
require("framework.lua_ex")
require("framework.lua_ex2")
local lfs = require("lfs")

local _isfirstlog = false
local NGINX_PATH = "/usr/local/openresty/nginx"

--在web端的输出
local _weblog = function(str, ...)
    local ret
    if string.find(str, "\n") ~= -1 then
        ret = string.gsub(str, "\n", "<br> ")
    end
    local exnewline = _isfirstlog == true and "" or "<br>"
    ngx.say(string.format(exnewline .. ret, ...))
    _isfirstlog = true
end

--兼容function输出
local fmt_outstr = function(outval)
    local ret
    local typeval = type(outval)
    if typeval == "function" then
        ret = typeval
    else
        ret = outval
    end
    _stdlog(ret)
end
--======================================

function d.init(isdev, logf)
    d.LN = require("framework.ln")
    --Logger
    local loglib = require("framework.log.init")
    local logf = type(logf) == "string" and logf or lfs.currentdir() .. "/temp/logs/http.log" 
    d.Logger = loglib.Logger.new()
    d.Logger:addHandler(loglib.FileHandler.new(logf, "a+", true))
    d._initUtils()
    d._initIncs()
    d["RELEASE_CONF"] = {
        isdev = isdev
    }
end

function d.set_ln(f, ftype)
    if ftype == "src" then
        d.LN:set_srcval(f)
    end
end
--======================================
function d._initUtils()
    d.UtilRds = require("framework.utils.utilrds")
end

function d._initIncs()
    d.PoolMgr = require("framework.db.poolmgr").new()
end

function d.initOrm(ormmap)
    d.Orm = require("framework.orm.init").new(ormmap)
end
--======================================
--FUNCTIONS
--======================================
--Package
d.loaded_packages = {}
local loaded_packages = d.loaded_packages
function d.register(name, package)
    d.loaded_packages[name] = package
end

function d.load(...)
    local names = {...}
    assert(#names > 0, "d.load() - invalid package names")

    local packages = {}
    for _, name in ipairs(names) do
        assert(type(name) == "string", string.format('d.load() - invalid package name "%s"', tostring(name)))
        if not loaded_packages[name] then
            local packageName = string.format("framework.decorator.%s", name)
            local cls = require(packageName)
            assert(cls, string.format('d.load() - package class "%s" load failed', packageName))
            loaded_packages[name] = cls
        end
        packages[#packages + 1] = loaded_packages[name]
    end
    return unpack(packages)
end

local load_ = d.load
local bind_
bind_ = function(target, ...)
    local t = type(target)
    assert(
        t == "table" or t == "userdata",
        string.format("d.bind() - invalid target, expected is object, actual is %s", t)
    )
    local names = {...}
    assert(#names > 0, "d.bind() - package names expected")

    load_(...)
    if not target.components_ then
        target.components_ = {}
    end
    for _, name in ipairs(names) do
        assert(type(name) == "string" and name ~= "", string.format('d.bind() - invalid package name "%s"', name))
        if not target.components_[name] then
            local cls = loaded_packages[name]
            for __, depend in ipairs(cls.depends or {}) do
                if not target.components_[depend] then
                    bind_(target, depend)
                end
            end
            local component = cls:create()
            target.components_[name] = component
            component:bind(target)
        end
    end

    return target
end
d.bind = bind_

function d.setmethods(target, component, methods)
    for _, name in ipairs(methods) do
        local method = component[name]
        target[name] = function(__, ...)
            return method(component, ...)
        end
    end
end

function d.unsetmethods(target, methods)
    for _, name in ipairs(methods) do
        target[name] = nil
    end
end

return d
